home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / varie / uae-0_64.lha / uae-0.6.4 / src / amiga.c next >
C/C++ Source or Header  |  1996-08-18  |  18KB  |  835 lines

  1. /* 
  2.  * UAE - The Un*x Amiga Emulator
  3.  *
  4.  * Amiga (native) specific support code; compiles with SAS/C 6.56,
  5.  * to get CyberGraphX support, add "DEFINE=_CYBERGFX" to the compiler
  6.  * flags in the smakefile. When running, hold down both Amiga keys
  7.  * to quit the emulation. The emulation also responds to ^C, which
  8.  * will abort it and to ^D which will reset it. Take care, the code
  9.  * appears to be very brittle and collapses easily if you switch
  10.  * screens. With CyberGraphX support enabled, the screen setup tries
  11.  * to be smart and falls back to standard screen update techniques
  12.  * if the screen to be opened does not belong to CyberGraphX. The
  13.  * 15/16/24 bit colour modes require that a graphics card like the
  14.  * CyberVision64 is installed that's not subject to byte ordering
  15.  * problems.
  16.  * 
  17.  * (c) 1996 Olaf `Olsen' Barthel
  18.  */
  19.  
  20. #include <intuition/intuitionbase.h>
  21. #include <intuition/pointerclass.h>
  22.  
  23. #include <graphics/gfxbase.h>
  24. #include <graphics/displayinfo.h>
  25.  
  26. #include <libraries/asl.h>
  27.  
  28. #include <exec/memory.h>
  29.  
  30. #include <dos/dos.h>
  31. #include <dos/dosasl.h>
  32.  
  33. #include <clib/intuition_protos.h>
  34. #include <clib/graphics_protos.h>
  35. #include <clib/exec_protos.h>
  36. #include <clib/dos_protos.h>
  37. #include <clib/asl_protos.h>
  38.  
  39. #include <pragmas/intuition_pragmas.h>
  40. #include <pragmas/graphics_pragmas.h>
  41. #include <pragmas/exec_pragmas.h>
  42. #include <pragmas/dos_pragmas.h>
  43. #include <pragmas/asl_pragmas.h>
  44.  
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <stdio.h>
  48.  
  49. #ifdef _CYBERGFX
  50. #include <cybergraphics/cybergraphics.h>
  51. #include <clib/cybergraphics_protos.h>
  52. #include <pragmas/cybergraphics_pragmas.h>
  53. #endif
  54.  
  55. /****************************************************************************/
  56.  
  57. #include "custom.h"
  58. #include "options.h"
  59. #include "keybuf.h"
  60. #include "autoconf.h"
  61. #include "xwin.h"
  62.  
  63. /****************************************************************************/
  64.  
  65. extern struct ExecBase        *SysBase;
  66. extern struct DosLibrary    *DOSBase;
  67.  
  68. struct IntuitionBase    *IntuitionBase;
  69. struct GfxBase        *GfxBase;
  70. struct Library        *AslBase;
  71. struct Library        *CyberGfxBase;
  72.  
  73. /****************************************************************************/
  74.  
  75. STATIC struct Screen    *Screen;
  76. STATIC struct Window    *Window;
  77. STATIC Object        *Pointer;
  78. STATIC ULONG         WindowMask;
  79.  
  80. STATIC struct RastPort    *TempRPort,
  81.             *RenderPort;
  82. STATIC struct BitMap    *BitMap;
  83. STATIC UBYTE        *Line;
  84.  
  85. STATIC LONG         ScreenHeight,
  86.              ScreenWidth;
  87.  
  88. /****************************************************************************/
  89.  
  90. int buttonstate[3];
  91. int lastmx, lastmy;
  92. int newmousecounters;
  93. long int xcolors[4096];
  94. struct vidbuf_description gfxvidinfo;
  95.  
  96. /****************************************************************************/
  97.  
  98. void m68k_reset(void);
  99.  
  100. /****************************************************************************/
  101.  
  102. STATIC VOID
  103. AmigaCleanup(VOID)
  104. {
  105.     if(BitMap)
  106.     {
  107.         WaitBlit();
  108.         FreeBitMap(BitMap);
  109.         BitMap = NULL;
  110.     }
  111.  
  112.     if(TempRPort)
  113.     {
  114.         FreeVec(TempRPort);
  115.         TempRPort = NULL;
  116.     }
  117.  
  118.     if(Line)
  119.     {
  120.         FreeVec(Line);
  121.         Line = NULL;
  122.     }
  123.  
  124.     if(Window)
  125.     {
  126.         CloseWindow(Window);
  127.         Window = NULL;
  128.     }
  129.  
  130.     if(Pointer)
  131.     {
  132.         DisposeObject(Pointer);
  133.         Pointer = NULL;
  134.     }
  135.  
  136.     if(Screen)
  137.     {
  138.         CloseScreen(Screen);
  139.         Screen = NULL;
  140.     }
  141.  
  142.     if(AslBase)
  143.     {
  144.         CloseLibrary(AslBase);
  145.         AslBase = NULL;
  146.     }
  147.  
  148.     if(GfxBase)
  149.     {
  150.         CloseLibrary(GfxBase);
  151.         GfxBase = NULL;
  152.     }
  153.  
  154.     if(IntuitionBase)
  155.     {
  156.         CloseLibrary(IntuitionBase);
  157.         IntuitionBase = NULL;
  158.     }
  159.  
  160.     if(CyberGfxBase)
  161.     {
  162.         CloseLibrary(CyberGfxBase);
  163.         CyberGfxBase = NULL;
  164.     }
  165. }
  166.  
  167. void
  168. flush_line(int y)
  169. {
  170.     if(!CyberGfxBase)
  171.     {
  172.         if(y >= 0 && y < ScreenHeight)
  173.         {
  174.             char *linebuf = y * gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
  175.  
  176.             CopyMem(linebuf,Line,ScreenWidth);
  177.             WritePixelLine8(RenderPort,0,y,ScreenWidth,Line,TempRPort);
  178.         }
  179.     }
  180. }
  181.  
  182. void
  183. flush_block(int ystart,int ystop)
  184. {
  185.     if(!CyberGfxBase)
  186.     {
  187.         if(ystart < 0)
  188.             ystart = 0;
  189.         else
  190.         {
  191.             if(ystart >= ScreenHeight)
  192.                 ystart = ScreenHeight - 1;
  193.         }
  194.  
  195.         if(ystop < 0)
  196.             ystop = 0;
  197.         else
  198.         {
  199.             if(ystop >= ScreenHeight)
  200.                 ystop = ScreenHeight - 1;
  201.         }
  202.  
  203.         if(ystart <= ystop)
  204.         {
  205.             char *mem;
  206.             int i;
  207.  
  208.             mem = ystart * gfxvidinfo.rowbytes + gfxvidinfo.bufmem;
  209.  
  210.             for(i = ystart ; i <= ystop ; i++, mem += gfxvidinfo.rowbytes)
  211.             {
  212.                 CopyMem(mem,Line,ScreenWidth);
  213.                 WritePixelLine8(RenderPort,0,i,ScreenWidth,Line,TempRPort);
  214.             }
  215.         }
  216.     }
  217. }
  218.  
  219. void
  220. flush_screen(int ystart,int ystop)
  221. {
  222. }
  223.  
  224. static int
  225. get_color(int r,int g,int b,long *cnp)
  226. {
  227.     ULONG Red,Green,Blue;
  228.     LONG Pen;
  229.  
  230.     Red    = 0x11111111 * r;
  231.     Green    = 0x11111111 * g;
  232.     Blue    = 0x11111111 * b;
  233.  
  234.     Pen = ObtainBestPen(Screen->ViewPort.ColorMap,Red,Green,Blue,
  235.         OBP_Precision,PRECISION_IMAGE,
  236.     TAG_DONE);
  237.  
  238.     if(Pen == -1)
  239.         return(0);
  240.     else
  241.     {
  242.         *cnp = Pen;
  243.  
  244.         return(1);
  245.     }
  246. }
  247.  
  248. int
  249. graphics_init(void)
  250. {
  251.     struct ScreenModeRequester *ScreenRequest;
  252.     ULONG DisplayID;
  253.     struct BitMap PointerBitMap;
  254.     UWORD PointerLine;
  255.     struct DimensionInfo Dims;
  256.     BOOL GotOne;
  257.     LONG Depth;
  258.     int vsize;
  259.  
  260.     atexit(AmigaCleanup);
  261.  
  262.     vsize = correct_aspect ? 2*numscrlines : numscrlines;
  263.  
  264.     if(!(gfxvidinfo.bufmem = malloc(800 * vsize)))
  265.     {
  266.         fprintf(stderr,"Sorry guv'nor, not enough memory for the line buffer.\n");
  267.         return(0);
  268.     }
  269.  
  270.     memset(gfxvidinfo.bufmem,0,800 * vsize);
  271.  
  272.     gfxvidinfo.rowbytes        = 800;
  273.     gfxvidinfo.pixbytes        = 1;
  274.     gfxvidinfo.maxblocklines    = 100;
  275.         gfxvidinfo.maxline = 100000; /* ??? */
  276.  
  277.     if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",39)))
  278.     {
  279.         fprintf(stderr,"Sorry guv'nor, unable to open intuition.library v39.\n");
  280.         return(0);
  281.     }
  282.  
  283.     if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",39)))
  284.     {
  285.         fprintf(stderr,"Sorry guv'nor, unable to open graphics.library v39.\n");
  286.         return(0);
  287.     }
  288.  
  289.     DisplayID = INVALID_ID;
  290.     GotOne = FALSE;
  291.  
  292.     while((DisplayID = NextDisplayInfo(DisplayID)) != INVALID_ID)
  293.     {
  294.         if(GetDisplayInfoData(NULL,(APTR)&Dims,sizeof(Dims),DTAG_DIMS,DisplayID))
  295.         {
  296.             if(Dims.MaxDepth >= 8)
  297.             {
  298.                 GotOne = TRUE;
  299.                 break;
  300.             }
  301.         }
  302.     }
  303.  
  304.     if(!GotOne)
  305.     {
  306.         fprintf(stderr,"Sorry guv'nor, your Amiga needs an AA chip set or a graphics card.\n");
  307.         return(0);
  308.     }
  309.  
  310.     if(!(AslBase = OpenLibrary("asl.library",38)))
  311.     {
  312.         fprintf(stderr,"Sorry guv'nor, unable to open asl.library v38.\n");
  313.         return(0);
  314.     }
  315.  
  316.     if(!(ScreenRequest = AllocAslRequest(ASL_ScreenModeRequest,NULL)))
  317.     {
  318.         fprintf(stderr,"Sorry guv'nor, unable to allocate screen mode requester.\n");
  319.         return(0);
  320.     }
  321.  
  322.     if(AslRequestTags(ScreenRequest,
  323.         ASLSM_TitleText,    "Select screen display mode",
  324.         ASLSM_MinDepth,        8,
  325.     TAG_DONE))
  326.     {
  327.         DisplayID = ScreenRequest->sm_DisplayID;
  328.  
  329.         GetDisplayInfoData(NULL,(APTR)&Dims,sizeof(Dims),DTAG_DIMS,DisplayID);
  330.  
  331.         Depth = Dims.MaxDepth;
  332.  
  333.         if(Depth > 8)
  334.             color_mode = 1;
  335.     }
  336.     else
  337.         DisplayID = INVALID_ID;
  338.  
  339.     FreeAslRequest(ScreenRequest);
  340.  
  341.     CloseLibrary(AslBase);
  342.     AslBase = NULL;
  343.  
  344.     if(DisplayID == INVALID_ID)
  345.         return(0);
  346.  
  347.     if(!(Screen = OpenScreenTags(NULL,
  348.         SA_DisplayID,    DisplayID,
  349.         SA_Depth,    Depth,
  350.         SA_Interleaved,    TRUE,
  351.         SA_ShowTitle,    FALSE,
  352.         SA_BackFill,    LAYERS_NOBACKFILL,
  353.         SA_Quiet,    TRUE,
  354.         SA_Behind,    TRUE,
  355.         SA_SharePens,    TRUE,
  356.         SA_Exclusive,    TRUE,
  357.         SA_Draggable,    FALSE,
  358.     TAG_DONE)))
  359.     {
  360.         fprintf(stderr,"Sorry guv'nor, unable to open the screen.\n");
  361.         return(0);
  362.     }
  363.  
  364.     ScreenWidth    = Screen->Width;
  365.     ScreenHeight    = Screen->Height;
  366.  
  367.     if(ScreenWidth > 800)
  368.         ScreenWidth = 800;
  369.  
  370.     if(ScreenHeight > 600)
  371.         ScreenHeight = 600;
  372.  
  373. #ifdef _CYBERGFX
  374.     if(CyberGfxBase = OpenLibrary("cybergraphics.library",40))
  375.     {
  376.         if(!IsCyberModeID(DisplayID) || ScreenHeight < vsize)
  377.         {
  378.             CloseLibrary(CyberGfxBase);
  379.             CyberGfxBase = NULL;
  380.         }
  381.     }
  382. #endif
  383.  
  384.     if(!(BitMap = AllocBitMap(Screen->Width,1,8,BMF_CLEAR|BMF_MINPLANES,Screen->RastPort.BitMap)))
  385.     {
  386.         fprintf(stderr,"Sorry guv'nor, unable to allocate BitMap.\n");
  387.         return(0);
  388.     }
  389.  
  390.     if(!(TempRPort = AllocVec(sizeof(struct RastPort),MEMF_ANY|MEMF_PUBLIC)))
  391.     {
  392.         fprintf(stderr,"Sorry guv'nor, unable to allocate RastPort.\n");
  393.         return(0);
  394.     }
  395.  
  396.     if(!(Line = AllocVec((Screen->Width + 15) & ~15,MEMF_ANY|MEMF_PUBLIC)))
  397.     {
  398.         fprintf(stderr,"Sorry guv'nor, unable to allocate raster buffer.\n");
  399.         return(0);
  400.     }
  401.  
  402.     CopyMem(&Screen->RastPort,TempRPort,sizeof(struct RastPort));
  403.     TempRPort->Layer = NULL;
  404.     TempRPort->BitMap = BitMap;
  405.  
  406.     PointerLine = 0x0000;
  407.  
  408.     InitBitMap(&PointerBitMap,2,16,1);
  409.     PointerBitMap.Planes[0] = (PLANEPTR)&PointerLine;
  410.     PointerBitMap.Planes[1] = (PLANEPTR)&PointerLine;
  411.  
  412.     if(!(Pointer = NewObject(NULL,POINTERCLASS,
  413.         POINTERA_BitMap,    &PointerBitMap,
  414.         POINTERA_WordWidth,    1,
  415.     TAG_DONE)))
  416.     {
  417.         fprintf(stderr,"Sorry guv'nor, unable to allocate blank mouse pointer.\n");
  418.         return(0);
  419.     }
  420.  
  421.     if(!(Window = OpenWindowTags(NULL,
  422.         WA_Width,        Screen->Width,
  423.         WA_Height,        Screen->Height,
  424.         WA_CustomScreen,    Screen,
  425.         WA_Backdrop,        TRUE,
  426.         WA_Borderless,        TRUE,
  427.         WA_BackFill,        LAYERS_NOBACKFILL,
  428.         WA_RMBTrap,        TRUE,
  429.         WA_IDCMP,        IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE,
  430.         WA_Pointer,        Pointer,
  431.         WA_ReportMouse,        TRUE,
  432.     TAG_DONE)))
  433.     {
  434.         fprintf(stderr,"Sorry guv'nor, unable to open the window.\n");
  435.         return(0);
  436.     }
  437.  
  438.     RenderPort = &Screen->RastPort;
  439.  
  440.     WindowMask = 1UL << Window->UserPort->mp_SigBit;
  441.  
  442.     SetRast(RenderPort,0);
  443.  
  444.     switch(Depth)
  445.     {
  446.         case 8:
  447.  
  448.             alloc_colors256(get_color);
  449.             break;
  450.  
  451.         case 15:
  452.  
  453.             alloc_colors64k(5,5,5,10,5,0);
  454.             break;
  455.  
  456.         case 16:
  457.  
  458.             alloc_colors64k(5,6,5,11,5,0);
  459.             break;
  460.  
  461.         case 24:
  462.         case 32:
  463.  
  464.             alloc_colors64k(8,8,8,16,8,0);
  465.             break;
  466.     }
  467.  
  468.     ScreenToFront(Screen);
  469.     ActivateWindow(Window);
  470.  
  471.     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
  472.  
  473.     lastmx = lastmy = 0;
  474.     newmousecounters = 0;
  475.  
  476. #ifdef _CYBERGFX
  477.     if(CyberGfxBase)
  478.     {
  479.         free(gfxvidinfo.bufmem);
  480.  
  481.         gfxvidinfo.bufmem    = (char *)GetCyberMapAttr(Screen->RastPort.BitMap,CYBRMATTR_DISPADR);
  482.         gfxvidinfo.rowbytes    = GetCyberMapAttr(Screen->RastPort.BitMap,CYBRMATTR_XMOD);
  483.         gfxvidinfo.pixbytes    = GetCyberMapAttr(Screen->RastPort.BitMap,CYBRMATTR_BPPIX);
  484.     }
  485. #endif
  486.     return(1);
  487. }
  488.  
  489. void
  490. graphics_leave(void)
  491. {
  492.     AmigaCleanup();
  493. }
  494.  
  495. void
  496. handle_events(void)
  497. {
  498.     ULONG Mask;
  499.  
  500.     Mask = SetSignal(0,SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|WindowMask);
  501.  
  502.     if(Mask & SIGBREAKF_CTRL_C)
  503.     {
  504.         PrintFault(ERROR_BREAK,"uae");
  505.         exit(RETURN_WARN);
  506.     }
  507.  
  508.     if(Mask & SIGBREAKF_CTRL_D)
  509.         m68k_reset();
  510.  
  511.     if(Mask & WindowMask)
  512.     {
  513.         struct IntuiMessage *IMsg;
  514.         ULONG MsgClass;
  515.         UWORD MsgCode;
  516.         WORD MsgX,MsgY;
  517.         WORD Button;
  518.         BOOL Quit;
  519.  
  520.         newmousecounters = 0;
  521.         Quit = FALSE;
  522.  
  523.         while(IMsg = (struct IntuiMessage *)GetMsg(Window->UserPort))
  524.         {
  525.             MsgClass    = IMsg->Class;
  526.             MsgCode        = IMsg->Code;
  527.             MsgX        = IMsg->MouseX;
  528.             MsgY        = IMsg->MouseY;
  529.  
  530.             if((IMsg->Qualifier & (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)) == (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND))
  531.                 Quit = TRUE;
  532.  
  533.             ReplyMsg(IMsg);
  534.  
  535.             switch(MsgClass)
  536.             {
  537.                 case IDCMP_RAWKEY:
  538.  
  539.                     if(MsgCode & IECODE_UP_PREFIX)
  540.                         record_key(((MsgCode & ~IECODE_UP_PREFIX) << 1) | 1);
  541.                     else
  542.                         record_key((MsgCode) << 1);
  543.  
  544.                     break;
  545.  
  546.                 case IDCMP_MOUSEBUTTONS:
  547.  
  548.                     switch(MsgCode & ~IECODE_UP_PREFIX)
  549.                     {
  550.                         case IECODE_LBUTTON:
  551.  
  552.                             Button = 0;
  553.                             break;
  554.  
  555.                         case IECODE_MBUTTON:
  556.  
  557.                             Button = 1;
  558.                             break;
  559.  
  560.                         case IECODE_RBUTTON:
  561.  
  562.                             Button = 2;
  563.                             break;
  564.                     }
  565.  
  566.                     if(MsgCode & IECODE_UP_PREFIX)
  567.                         buttonstate[Button] = 0;
  568.                     else
  569.                         buttonstate[Button] = 1;
  570.  
  571.                     break;
  572.  
  573.                 case IDCMP_MOUSEMOVE:
  574.  
  575.                     lastmx = MsgX;
  576.                     lastmy = MsgY;
  577.  
  578.                     newmousecounters = 1;
  579.  
  580.                     break;
  581.             }
  582.         }
  583.  
  584.         if(Quit)
  585.             exit(RETURN_OK);
  586.     }
  587. }
  588.  
  589. int
  590. debuggable(void)
  591. {
  592.     return 1;
  593. }
  594.  
  595. int
  596. needmousehack(void)
  597. {
  598.     return 1;
  599. }
  600.  
  601. void
  602. LED(int on)
  603. {
  604. }
  605.  
  606. /****************************************************************************/
  607.  
  608. int quit_program;
  609.  
  610. int
  611. gui_init(void)
  612. {
  613.     quit_program = 0;
  614. }
  615.  
  616. void
  617. gui_exit(void)
  618. {
  619. }
  620.  
  621. void
  622. gui_led(int led, int on)
  623. {
  624. }
  625.  
  626. void
  627. gui_filename(int num, char *name)
  628. {
  629. }
  630.  
  631. void
  632. gui_handle_events(void)
  633. {
  634. }
  635.  
  636. /****************************************************************************/
  637.  
  638. int    opterr = 1;            /* error => print message */
  639. int    optind = 1;            /* next argv[] index */
  640. char    *optarg = NULL;            /* option parameter if any */
  641.  
  642. static int
  643. Err( name, mess, c )            /* returns '?' */
  644.     char    *name;            /* program name argv[0] */
  645.     char    *mess;            /* specific message */
  646.     int    c;            /* defective option letter */
  647.     {
  648.     if ( opterr )
  649.         (void) fprintf( stderr,
  650.                 "%s: %s -- %c\n",
  651.                 name, mess, c
  652.                   );
  653.  
  654.     return '?';            /* erroneous-option marker */
  655.     }
  656.  
  657. int
  658. getopt( argc, argv, optstring )        /* returns letter, '?', EOF */
  659.     int        argc;        /* argument count from main */
  660.     char        *argv[];    /* argument vector from main */
  661.     char        *optstring;    /* allowed args, e.g. "ab:c" */
  662.     {
  663.     static int    sp = 1;        /* position within argument */
  664.     register int    osp;        /* saved `sp' for param test */
  665.     register int    c;        /* option letter */
  666.     register char    *cp;        /* -> option in `optstring' */
  667.  
  668.     optarg = NULL;
  669.  
  670.     if ( sp == 1 )            /* fresh argument */
  671.         if ( optind >= argc        /* no more arguments */
  672.           || argv[optind][0] != '-'    /* no more options */
  673.           || argv[optind][1] == '\0'    /* not option; stdin */
  674.            )
  675.             return EOF;
  676.         else if ( strcmp( argv[optind], "--" ) == 0 )
  677.             {
  678.             ++optind;    /* skip over "--" */
  679.             return EOF;    /* "--" marks end of options */
  680.             }
  681.  
  682.     c = argv[optind][sp];        /* option letter */
  683.     osp = sp++;            /* get ready for next letter */
  684.  
  685.     if ( argv[optind][sp] == '\0' )    /* end of argument */
  686.         {
  687.         ++optind;        /* get ready for next try */
  688.         sp = 1;            /* beginning of next argument */
  689.         }
  690.  
  691.     if ( c == ':'            /* optstring syntax conflict */
  692.       || (cp = strchr( optstring, c )) == NULL    /* not found */
  693.        )
  694.         return Err( argv[0], "illegal option", c );
  695.  
  696.     if ( cp[1] == ':' )        /* option takes parameter */
  697.         {
  698.         if ( osp != 1 )
  699.             return Err( argv[0],
  700.                     "option must not be clustered",
  701.                     c
  702.                   );
  703.  
  704.         if ( sp != 1 )        /* reset by end of argument */
  705.             return Err( argv[0],
  706.                    "option must be followed by white space",
  707.                     c
  708.                   );
  709.  
  710.         if ( optind >= argc )
  711.             return Err( argv[0],
  712.                     "option requires an argument",
  713.                     c
  714.                   );
  715.  
  716.         optarg = argv[optind];    /* make parameter available */
  717.         ++optind;        /* skip over parameter */
  718.         }
  719.  
  720.     return c;
  721.     }
  722.  
  723. /****************************************************************************/
  724.  
  725. static void usage(void)
  726. {
  727.     printf("UAE - The Un*x Amiga emulator\n");
  728.     printf("Summary of command-line options:\n");
  729.     printf("  -h                       : Print help\n");
  730.     printf("  -m VOLNAME:mount_point   : mount file system at <mount point> as AmigaDOS\n"
  731.        "                             volume VOLNAME:\n");
  732.     printf("  -M VOLNAME:mount_point   : like -m, but mount read-only\n");
  733.     printf("  -a                       : Don't mount the harddisk file automatically.\n"
  734.        "                             Useful only for testing.\n");
  735.     printf("  -S                       : Turn off sound support (if it is configured)\n");
  736.     printf("  -s                       : Emulate 1 MB slow memory at 0xC00000\n");
  737.     printf("  -F n                     : Emulate n MB fast memory at 0x200000\n");
  738.     printf("  -f n                     : Set the frame rate to 1/n\n");
  739.     printf("  -x                       : Use visible cross-hair cursor (X Windows version)\n");
  740.     printf("  -D                       : Start up the built-in debugger\n");
  741.     printf("  -[0123] file             : Use file instead of df[0123].adf as disk image file\n");
  742.     printf("  -r file                  : Use file as ROM image instead of kick.rom\n");
  743.     printf("  -J                       : Fake joystick emulation with the numeric pad.\n");
  744.     printf("  -g                       : Turn on gfx-lib replacement.\n");
  745.     printf("  -d mode                  : Select resolution with the mode parameter.\n");
  746.     printf("  -H mode                  : Set the number of colors with the mode parameter.\n");
  747.     printf("\n");
  748.     printf("Valid resolutions: 0 (320x200); 1 (320x240); 2 (320x400); 3 (800x600);\n"
  749.        "                   4 (800x600, correct aspect)\n"
  750.        "Valid color modes: 0 (256 colors); 1 (32768 colors); 2 (65536 colors)\n"
  751.        "UAE may choose to ignore the color mode/resolution setting.\n");
  752. }
  753.  
  754. void parse_cmdline(int argc, char **argv)
  755. {
  756. extern ULONG fastmem_size;
  757.  
  758.     int c;
  759.  
  760.     while(((c = getopt(argc, argv, "l:Df:gd:hxF:asSJm:M:0:1:2:3:r:H:")) != EOF)) switch(c) {
  761.      case 'h': usage();    exit(0);
  762.  
  763.      case '0': strncpy(df0, optarg, 255); df0[255] = 0;    break;
  764.      case '1': strncpy(df1, optarg, 255); df1[255] = 0; break;
  765.      case '2': strncpy(df2, optarg, 255); df2[255] = 0; break;
  766.      case '3': strncpy(df3, optarg, 255); df3[255] = 0; break;
  767.      case 'r': strncpy(romfile, optarg, 255); romfile[255] = 0; break;
  768.  
  769.      case 'm':
  770.      case 'M':
  771.     {
  772.         /* mount file system (repeatable)
  773.          * syntax: [-m | -M] VOLNAME:/mount_point
  774.          * example: -M CDROM:/cdrom -m UNIXFS:./disk
  775.          */
  776.         static int mount_seen = 0;
  777.         char buf[256];
  778.         char *s2;
  779.         int readonly = (c == 'M');
  780.  
  781.         if (mount_seen)
  782.         fprintf(stderr, "warning: multiple mounts confuse Kickstart 1.3\n");
  783.         mount_seen = 1;
  784.         strncpy(buf, optarg, 255); buf[255] = 0;
  785.         s2 = strchr(buf, ':');
  786.         if(s2) {
  787.         *s2++ = '\0';
  788.         add_filesys_unit(buf, s2, readonly);
  789.         } else {
  790.         fprintf(stderr, "Usage: [-m | -M] VOLNAME:/mount_point\n");
  791.         }
  792.     }
  793.     break;
  794.  
  795.      case 'S': produce_sound = 0; break;
  796.      case 'f': framerate = atoi(optarg); break;
  797.      case 'x': use_xhair = 1; break;
  798.      case 'D': use_debugger = 1; break;
  799.      case 'J': fake_joystick = 1; break;
  800.      case 'a': automount_uaedev = 0; break;
  801.      case 's': use_slow_mem = 1; break;
  802.      case 'g': use_gfxlib = 1; break;
  803.  
  804.      case 'F':
  805.     fastmem_size = atoi(optarg) * 0x100000;
  806.     if (fastmem_size != 0x100000 && fastmem_size != 0x200000
  807.         && fastmem_size != 0x400000 && fastmem_size != 0x800000)
  808.     {
  809.         fastmem_size = 0;
  810.         fprintf(stderr, "Unsupported fastmem size!\n");
  811.     }
  812.  
  813.     break;
  814.  
  815.      case 'd':
  816.     screen_res = atoi(optarg);
  817.     if (screen_res >= 0 && screen_res <= 4) {
  818.     } else {
  819.         fprintf(stderr, "Bad video mode selected. Using default.\n");
  820.         screen_res = 3;
  821.     }
  822.     /*dont_want_aspect = screen_res != 4;*/
  823.     use_lores = screen_res < 3;
  824.     break;
  825.  
  826.      case 'H':
  827.     color_mode = atoi(optarg);
  828.     if (color_mode < 0 || color_mode > 2) {
  829.         fprintf(stderr, "Bad color mode selected. Using default.\n");
  830.         color_mode = 0;
  831.     }
  832.      break;
  833.     }
  834. }
  835.